<script setup lang="ts">
import { ref, reactive, h, onMounted } from "vue";
import { DynamicTable } from "@/components/DynamicTable";
import { PaginationConfig, TableColumn } from "@/components/DynamicTable/types";
import DynamicForm from "@/components/DynamicForm/index.vue";
import type { DynamicFormInstance } from "@/components/DynamicForm/types";
import { FormItemConfig } from "@/components/DynamicForm/types";
import {
  ElMessage,
  ElMessageBox,
  ElTag,
  ElButton,
  ElDialog,
  ElProgress,
} from "element-plus";
import { Refresh } from "@element-plus/icons-vue";
import {
  getSubdomainList,
  scanSubdomain,
  addSubdomain,
  deleteSubdomain,
  getBeianList,
} from "../servers";

const props = defineProps<{
  task: string;
}>();

const pagination = reactive<PaginationConfig>({
  currentPage: 1,
  pageSize: 20,
  total: 0,
  pageSizes: [20, 50, 100],
  layout: "total, sizes, prev, pager, next",
  background: true,
});

const subdomainList = ref([]);
const loading = ref(false);
const searchFormRef = ref<DynamicFormInstance>();

const searchForm = reactive({
  keyword: "",
});

const searchConfig: FormItemConfig[] = [
  {
    key: "keyword",
    name: "关键词",
    type: "input",
    placeholder: "搜索子域名或IP地址",
    params: {
      clearable: true,
      style: { width: "300px" },
    },
  },
];

const columns = ref<TableColumn[]>([
  {
    label: "子域名",
    prop: "subdomain",
    width: 250,
    show: true,
  },
  {
    label: "IP地址",
    prop: "ip_address",
    width: 150,
    show: true,
  },
  {
    label: "权重",
    prop: "weight",
    width: 100,
    show: true,
    render: (row) => {
      if (!row.weight) return "N/A";
      return h(
        "span",
        {
          style: {
            color:
              row.weight >= 100
                ? "#f56c6c"
                : row.weight >= 50
                ? "#e6a23c"
                : "#67c23a",
            fontWeight: "bold",
          },
        },
        row.weight
      );
    },
  },
  {
    label: "来源",
    prop: "source",
    width: 100,
    show: true,
    render: (row) => {
      return h(
        ElTag,
        {
          type: row.source === "fofa" ? "warning" : "success",
          size: "small",
        },
        () => (row.source === "fofa" ? "FOFA" : "手动")
      );
    },
  },
  {
    label: "备案域名",
    prop: "beian_domain",
    width: 200,
    show: true,
  },
  {
    label: "创建时间",
    prop: "created_at",
    width: 160,
    show: true,
  },
  {
    label: "操作",
    prop: "action",
    width: 150,
    show: true,
    slot: "action",
    fixed: "right",
  },
]);

const beianOptions = ref<any[]>([]);

// 扫描对话框
const scanDialogVisible = ref(false);
const scanForm = reactive({
  beianId: null,
});
const scanning = ref(false);
const scanProgress = ref(0);

// 手动添加对话框
const addDialogVisible = ref(false);
const addForm = reactive({
  subdomain: "",
  ipAddress: "",
  beianId: null,
});
const addFormRef = ref<DynamicFormInstance>();

const fetchSubdomainList = async () => {
  loading.value = true;
  try {
    const params: any = {
      page: pagination.currentPage,
      size: pagination.pageSize,
      keyword: searchForm.keyword,
      order_by: "weight", // 默认按权重排序
    };
    // 移除空值
    Object.keys(params).forEach((key) => {
      if (
        params[key] === "" ||
        params[key] === null ||
        params[key] === undefined
      ) {
        delete params[key];
      }
    });
    const { data } = await getSubdomainList(params);
    subdomainList.value = data.list || [];
    pagination.total = data.total || 0;
  } catch (error) {
    ElMessage.error("获取子域名列表失败");
  } finally {
    loading.value = false;
  }
};

const fetchBeianOptions = async () => {
  try {
    const { data } = await getBeianList({ size: 1000 });
    beianOptions.value =
      (data.list || []).map((item: any) => ({
        label: item.domain,
        value: item.id,
      })) || [];
  } catch (error) {
    console.error("获取备案域名选项失败", error);
  }
};

const handleSearch = (value: any) => {
  searchForm.keyword = value.keyword || "";
  pagination.currentPage = 1;
  fetchSubdomainList();
};

const handleSearchReset = () => {
  searchFormRef.value?.resetFields();
  searchForm.keyword = "";
  pagination.currentPage = 1;
  fetchSubdomainList();
};

const handlePageChange = (page: number) => {
  pagination.currentPage = page;
  fetchSubdomainList();
};

const handleSizeChange = (size: number) => {
  pagination.pageSize = size;
  pagination.currentPage = 1;
  fetchSubdomainList();
};

const handleOpenScanDialog = () => {
  scanForm.beianId = null;
  scanDialogVisible.value = true;
};

const handleScanSubdomain = async () => {
  if (!scanForm.beianId) {
    ElMessage.warning("请选择备案域名");
    return;
  }
  scanning.value = true;
  scanProgress.value = 0;
  scanDialogVisible.value = false;
  try {
    await scanSubdomain({ beian_id: scanForm.beianId, auto_save: true });
    ElMessage.success("子域名扫描任务创建成功");
    // 模拟进度更新
    const timer = setInterval(() => {
      scanProgress.value += 10;
      if (scanProgress.value >= 100) {
        clearInterval(timer);
        scanning.value = false;
        scanProgress.value = 0;
        fetchSubdomainList();
      }
    }, 500);
  } catch (error) {
    ElMessage.error("创建扫描任务失败");
    scanning.value = false;
  }
};

const handleOpenAddDialog = () => {
  addForm.subdomain = "";
  addForm.ipAddress = "";
  addForm.beianId = null;
  addDialogVisible.value = true;
};

const handleAddSubdomain = async () => {
  if (!addForm.subdomain || !addForm.ipAddress) {
    ElMessage.warning("请填写完整的子域名和IP地址信息");
    return;
  }
  if (!addForm.beianId) {
    ElMessage.warning("请选择备案域名");
    return;
  }
  try {
    await addSubdomain({
      beian_id: addForm.beianId,
      subdomain: addForm.subdomain,
      ip_address: addForm.ipAddress,
    });
    ElMessage.success("子域名添加成功");
    addDialogVisible.value = false;
    fetchSubdomainList();
  } catch (error) {
    ElMessage.error("添加子域名失败");
  }
};

const handleDelete = (row: any) => {
  ElMessageBox.confirm("确定删除该子域名吗？", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    try {
      await deleteSubdomain({ id: row.id });
      ElMessage.success("删除成功");
      fetchSubdomainList();
    } catch (error) {
      ElMessage.error("删除失败");
    }
  });
};

onMounted(() => {
  fetchBeianOptions();
  fetchSubdomainList();
});
</script>

<template>
  <div>
    <!-- 搜索表单 -->
    <el-card shadow="never">
      <div class="search-form-container">
        <DynamicForm
          ref="searchFormRef"
          v-model="searchForm"
          :form-config="searchConfig"
          :gutter="16"
          label-width="80px"
          type="search"
          @search="handleSearch"
          @reset="handleSearchReset"
        />
      </div>
    </el-card>

    <div style="height: 10px"></div>

    <el-card>
      <DynamicTable
        :pagination="pagination"
        :columns="columns"
        :data="subdomainList"
        :loading="loading"
        @current-page-change="handlePageChange"
        @size-change="handleSizeChange"
      >
        <template #toolbar-left>
          <el-button type="primary" @click="handleOpenAddDialog"
            >手动添加</el-button
          >
          <el-button type="warning" @click="handleOpenScanDialog">
            FOFA扫描
          </el-button>
        </template>

        <template #toolbar-right>
          <el-button type="success" :icon="Refresh" @click="fetchSubdomainList">
            刷新
          </el-button>
        </template>

        <template #action="{ row }">
          <el-button type="danger" size="small" @click="handleDelete(row)">
            删除</el-button
          >
        </template>
      </DynamicTable>
    </el-card>

    <!-- FOFA扫描对话框 -->
    <el-dialog v-model="scanDialogVisible" title="子域名扫描" width="500px">
      <el-form :model="scanForm" label-width="100px">
        <el-form-item label="备案域名" required>
          <el-select
            v-model="scanForm.beianId"
            placeholder="选择备案域名"
            style="width: 100%"
            filterable
          >
            <el-option
              v-for="option in beianOptions"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="scanDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleScanSubdomain"
          >开始扫描</el-button
        >
      </template>
    </el-dialog>

    <!-- 扫描进度对话框 -->
    <el-dialog
      v-model="scanning"
      title="扫描中..."
      :close-on-click-modal="false"
      width="500px"
    >
      <div class="scan-progress">
        <p><strong>状态:</strong> 正在扫描中...</p>
        <el-progress :percentage="scanProgress" />
        <p style="margin-top: 10px; color: #909399">正在从FOFA获取子域名数据</p>
      </div>
    </el-dialog>

    <!-- 手动添加对话框 -->
    <el-dialog v-model="addDialogVisible" title="手动添加子域名" width="500px">
      <el-form :model="addForm" label-width="100px">
        <el-form-item label="子域名" required>
          <el-input
            v-model="addForm.subdomain"
            placeholder="请输入子域名，如: www.example.com"
          />
        </el-form-item>
        <el-form-item label="IP地址" required>
          <el-input
            v-model="addForm.ipAddress"
            placeholder="请输入IP地址，如: 192.168.1.1"
          />
        </el-form-item>
        <el-form-item label="备案域名">
          <el-select
            v-model="addForm.beianId"
            placeholder="选择备案域名（可选）"
            style="width: 100%"
            filterable
          >
            <el-option
              v-for="option in beianOptions"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="addDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleAddSubdomain">添加</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
.search-form-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.scan-progress {
  p {
    margin: 10px 0;
  }
}
</style>
